<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
<HTML>
<HEAD>



<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<META name="GENERATOR" content="hevea 1.08">
<LINK rel="stylesheet" type="text/css" href="obsman.css">
<TITLE>
The Finite Domains Library
</TITLE>
</HEAD>
<BODY >
<A HREF="obsman001.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="obsman003.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H1 CLASS="chapter"><A NAME="htoc2">Chapter&nbsp;2</A>&nbsp;&nbsp;The Finite Domains Library</H1>
<A NAME="chapdomains"></A>
<A NAME="@default0"></A>
The library <B>fd.pl</B>
implements constraints over finite domains that can contain
integer as well as atomic (i.e. atoms, strings, floats, etc.)
and ground compound (e.g. <I>f(a, b)</I>)
elements.
Modules that use the library must start with the directive
<BLOCKQUOTE CLASS="quote">
<B>:- use_module(library(fd)).</B>
</BLOCKQUOTE>
<A NAME="toc1"></A>
<H2 CLASS="section"><A NAME="htoc3">2.1</A>&nbsp;&nbsp;Terminology</H2>
Some of the terms frequently used in this chapter are explained below.
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<B>domain variable</B><DD CLASS="dd-description">
<A NAME="@default1"></A>
A domain variable is a variable which can be instantiated only
to a value from a given finite set.
Unification with a term outside of this domain fails.
The domain can be associated with the variable using the predicate 
<A HREF="../bips/lib/fd/NN-2.html"><B>::/2</B></A><A NAME="@default2"></A>.
Built-in predicates that expect domain variables
treat atomic and other ground terms as variables with singleton domains.<BR>
<BR>
<DT CLASS="dt-description"><B>integer domain variable</B><DD CLASS="dd-description">
<A NAME="@default3"></A>
An integer domain variable is a domain variable
whose domain contains only integer numbers.
Only such variables are accepted in inequality constraints
and in rational terms.
Note that a non-integer domain variable can become
an integer domain variable when the non-integer values
are removed from its domain.<BR>
<BR>
<DT CLASS="dt-description"><B>integer interval</B><DD CLASS="dd-description">
An integer interval is written as
<DIV CLASS="center">
<I>Min .. Max</I>
</DIV>
with integer expressions
<I><I>Min</I> &#8804; <I>Max</I></I>
and it represents
the set
<DIV CLASS="center">
{Min, Min + 1, ..., Max}.
</DIV><BR>
<BR>
<DT CLASS="dt-description"><B>linear term</B><DD CLASS="dd-description">
A linear term is a linear integer combination of integer domain variables.
The constraint predicates accept linear terms even in a non-canonical form,
containing functors +, - and *,
e.g.
<DIV CLASS="center">
5*(3+(4&minus;6)*<I>Y</I>&minus;<I>X</I>*3).
</DIV>
If the constraint predicates encounter 
a variable without a domain, they
give it a default domain -10000000..10000000.
<A NAME="@default4"></A>
Note that arithmetic operations on linear terms are performed
with standard machine word integers without any overflow checks.
If the domain ranges or coefficients are too large,
the operation will not yield correct results.
Both the maximum and minimum value of a linear term must
be representable in a machine word, and so must
the maximum and minimum value of every


<I><I>c</I></I><SUB><I><I>i</I></I></SUB><I> <I>x</I></I><SUB><I><I>i</I></I></SUB>

term.<BR>
<BR>
<DT CLASS="dt-description"><B>rational term</B><DD CLASS="dd-description">
A rational term is a term constructed from integers and integer
domain variables using the arithmetic operations
<B>+, &minus;, *, /</B>.
Besides that, every subexpression of the form <I>VarA/VarB</I> must have
an integer value in the solution.
The system replaces such a subexpression by a new variable <I>X</I>
and adds a new constraint <I>VarA #= VarB * X</I>.
Similarly, all subexpressions of the form <I>VarA*VarB</I>
are replaced by a new variable <I>X</I>
and a new constraint <I>X #= VarA * VarB</I> is added,
so that in the internal representation, the term is converted
to a linear term.<BR>
<BR>
<DT CLASS="dt-description"><B>constraint expression</B><DD CLASS="dd-description">
A constraint expression is either an arithmetic constraint
or a combination of constraint expressions using the
logical FD connectives
<B>#/\/2, #\//2, #=&gt;/2, #&lt;=&gt;/2, #\+/1</B>.
</DL>
<A NAME="toc2"></A>
<H2 CLASS="section"><A NAME="htoc4">2.2</A>&nbsp;&nbsp;Constraint Predicates</H2>
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/NN-2.html"><B>?Vars :: ?Domain</B></A><A NAME="@default5"></A><BR>
<A NAME="@default6"></A>
<A NAME="@default7"></A>
<I>Vars</I> is a variable or a list of variables
with the associated domain <I>Domain</I>.
<I>Domain</I> can be a closed integer interval denoted as <I>Min .. Max</I>,
or a list of intervals and/or atomic or ground elements.
Although the domain can contain any compound terms that contain
no variable,
the functor <I>../2</I> is reserved to denote integer intervals
and thus <I>1..10</I> always means an interval and <I>a..b</I>
is not accepted as a compound domain element.<BR>
<BR>
If <I>Vars</I> is already a domain variable, its domain will be updated
according to the new domain; if it is instantiated, the predicate checks
if the value lies in the domain.
Otherwise, if <I>Vars</I> is a free variable, it is converted to a domain
variable.
If <I>Vars</I> is a domain variable and <I>Domain</I> is free,
it is bound to the list of elements and integer intervals
representing the domain of the variable
(see also <A HREF="../bips/lib/fd/dvar_domain-2.html"><B>dvar_domain/2</B></A><A NAME="@default8"></A> which returns the actual domain).<BR>
<BR>
When a free variable obtains a finite domain or when the domain
of a domain variable is updated, the <B>constrained</B>
list of its <B>suspend</B> attribute is woken, if it has one.
<A NAME="@default9"></A><BR>
<BR>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/integers-1.html"><B>integers(+Vars)</B></A><A NAME="@default10"></A><BR>
<A NAME="@default11"></A>
This constrains the list of variables Vars to have integer domains. Any
non-domain variables in Vars will be given the default integer domain.<BR>
<BR>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/NN-3.html"><B>::(?Var, ?Domain, ?B)</B></A><A NAME="@default12"></A><BR>
<A NAME="@default13"></A>
<I>B</I> is equal to 1 iff the domain of the finite domain variable <I>Var</I>
is a subset of <I>Domain</I> and 0 otherwise.<BR>
<BR>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/atmost-3.html"><B>atmost(+Number, ?List, +Val)</B></A><A NAME="@default14"></A><BR>
<A NAME="@default15"></A>
At most <I>Number</I> elements of the list <I>List</I> of domain variables
and ground terms are equal to the ground value <I>Val</I>.<BR>
<BR>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/constraints_number-2.html"><B>constraints_number(+DVar, -Number)</B></A><A NAME="@default16"></A><BR>
<A NAME="@default17"></A>
<I>Number</I> is the number of constraints and suspended goals
currently attached to the variable <I>DVar</I>.
Note that this number may not correspond to the exact number
of <I>different</I> constraints attached to <I>DVar</I>, as goals
in different suspending lists are counted separately.
This predicate is often used when looking for the most or least constrained
variable from a set of domain variables (see also <A HREF="../bips/lib/fd/deleteffc-3.html"><B>deleteffc/3</B></A><A NAME="@default18"></A>).<BR>
<BR>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/element-3.html"><B>element(?Index, +List, ?Value)</B></A><A NAME="@default19"></A><BR>
<A NAME="@default20"></A>
The <I>Index</I>'th element of the ground list <I>List</I>
is equal to <I>Value</I>.
<I>Index</I> and <I>Value</I> can be either plain variables,
in which case a domain will be associated to them, or domain variables.
Whenever the domain of <I>Index</I> or <I>Value</I> is updated,
the predicate is woken and the domains are updated accordingly.<BR>
<BR>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/fd_eval-1.html"><B>fd_eval(+E)</B></A><A NAME="@default21"></A><BR>
<A NAME="@default22"></A>
The constraint expression <I>E</I> is evaluated on runtime
and no compile-time processing is performed.
This might be necessary in the situations where the
default compile-time transformation of the given expression
is not suitable, e.g. because it would require type or mode information.<BR>
<BR>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/indomain-1.html"><B>indomain(+DVar)</B></A><A NAME="@default23"></A><BR>
<A NAME="@default24"></A>
This predicate instantiates the domain variable <I>DVar</I> to 
an element of its domain; on backtracking the subsequent values are taken.
It is used, for example, to find a value of <I>DVar</I> which is consistent
with all currently imposed constraints.
If <I>DVar</I> is a ground term, it succeeds.
Otherwise, if it is not a domain variable, an error is raised.<BR>
<BR>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/is_domain-1.html"><B>is_domain(?Term)</B></A><A NAME="@default25"></A><BR>
<A NAME="@default26"></A>
Succeeds if <I>Term</I> is a domain variable.<BR>
<BR>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/is_integer_domain-1.html"><B>is_integer_domain(?Term)</B></A><A NAME="@default27"></A><BR>
<A NAME="@default28"></A>
Succeeds if <I>Term</I> is an integer domain variable.<BR>
<BR>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/min_max-2.html"><B>min_max(+Goal, ?C)</B></A><A NAME="@default29"></A><BR>
<A NAME="@default30"></A>
If <I>C</I> is a linear term,
a solution of the goal <I>Goal</I> is found that minimises the
value of <I>C</I>.
If <I>C</I> is a list of linear terms, the returned solution
minimises the maximum value of terms in the list.
The solution is found using the <I>branch and bound</I> method;
as soon as a partial solution is found that is worse than a previously
found solution, failure is forced and a new solution is searched for.
When a new better solution is found, the bound is updated and
the search restarts from the beginning.
Each time a new better solution is found, the event 280 is raised.
If a solution does not make <I>C</I> ground, an error is raised,
unless exactly one variable in the list <I>C</I> remains free,
in which case the system tries to instantiate it to its minimum.<BR>
<BR>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/minimize-2.html"><B>minimize(+Goal, ?Term)</B></A><A NAME="@default31"></A><BR>
<A NAME="@default32"></A>
Similar to <A HREF="../bips/lib/fd/min_max-2.html"><B>min_max/2</B></A><A NAME="@default33"></A>, but <I>Term</I> must be an integer domain variable.
When a new better solution is found, the search does not restart
from the beginning, but a failure is forced and the search continues.
Each time a new better solution is found, the event 280 is raised.
Often <A HREF="../bips/lib/fd/minimize-2.html"><B>minimize/2</B></A><A NAME="@default34"></A> is faster than <A HREF="../bips/lib/fd/min_max-2.html"><B>min_max/2</B></A><A NAME="@default35"></A>, sometimes
<A HREF="../bips/lib/fd/min_max-2.html"><B>min_max/2</B></A><A NAME="@default36"></A> might run faster, but it is difficult to predict 
which one is more appropriate for a given problem.<BR>
<BR>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/min_max-4.html"><B>min_max(+Goal, ?Template, ?Solution, ?C)</B></A><A NAME="@default37"></A>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/minimize-4.html"><B>minimize(+Goal, ?Template, ?Solution, ?Term)</B></A><A NAME="@default38"></A><BR>
<A NAME="@default39"></A>
<A NAME="@default40"></A>
Similar to <A HREF="../bips/lib/fd/min_max-2.html"><B>min_max/2</B></A><A NAME="@default41"></A>
and <A HREF="../bips/lib/fd/minimize-2.html"><B>minimize/2</B></A><A NAME="@default42"></A>,
but the variables in <I>Goal</I> do not get
instantiated to their optimum solutions. Instead, <I>Solutions</I> will
be unified with a copy of <I>Template</I> where the variables are replaced
with their minimized values. Typically, the template will contain
all or a subset of <I>Goal</I>'s variables.<BR>
<BR>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/min_max-5.html"><B>min_max(+Goal, ?C, +Low, +High, +Percent)</B></A><A NAME="@default43"></A>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/minimize-5.html"><B>minimize(+Goal, ?Term, +Low, +High, +Percent)</B></A><A NAME="@default44"></A><BR>
<A NAME="@default45"></A>
<A NAME="@default46"></A>
Similar to <A HREF="../bips/lib/fd/min_max-2.html"><B>min_max/2</B></A><A NAME="@default47"></A>
and <A HREF="../bips/lib/fd/minimize-2.html"><B>minimize/2</B></A><A NAME="@default48"></A>,
however the branch and bound method
starts with the assumption that the value to be minimised is less than
or equal to <I>High</I>.
Moreover, as soon as a solution is found
whose minimised value is less than <I>Low</I>, this solution is returned.
Solutions within the range of <I>Percent</I> % are considered
equivalent and so the search for next better solution starts
with a minimised value <I>Percent</I> % less than the previously found one.
<I>Low</I>, <I>High</I> and <I>Percent</I> must be integers.<BR>
<BR>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/min_max-6.html"><B>min_max(+Goal, ?C, +Low, +High, +Percent, +Timeout)</B></A><A NAME="@default49"></A>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/minimize-6.html"><B>minimize(+Goal, ?Term, +Low, +High, +Percent, +Timeout)</B></A><A NAME="@default50"></A><BR>
<A NAME="@default51"></A>
<A NAME="@default52"></A>
Similar to <A HREF="../bips/lib/fd/min_max-5.html"><B>min_max/5</B></A><A NAME="@default53"></A>
and <A HREF="../bips/lib/fd/minimize-5.html"><B>minimize/5</B></A><A NAME="@default54"></A>,
but after <I>Timeout</I> seconds
the search is aborted and the best solution found so far is
returned.<BR>
<BR>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/min_max-8.html"><B>min_max(+Goal, ?Template, ?Solution, ?C, +Low, +High, +Percent, +Timeout)</B></A><A NAME="@default55"></A>
<DT CLASS="dt-description"><DD CLASS="dd-description"> <A HREF="../bips/lib/fd/minimize-8.html"><B>minimize(+Goal, ?Template, ?Solution, ?Term, +Low, +High, +Percent, +Timeout)</B></A><A NAME="@default56"></A><BR>
<A NAME="@default57"></A>
<A NAME="@default58"></A>
The most general variants of the above, with all the optinal parameters.</DL>
<A NAME="toc3"></A>
<H2 CLASS="section"><A NAME="htoc5">2.3</A>&nbsp;&nbsp;Arithmetic Constraint Predicates</H2>
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<B>?T1 #\= ?T2</B><DD CLASS="dd-description">
<A NAME="@default59"></A>
The value of the rational term <I>T1</I> is not equal to the value of the
rational term <I>T2</I>.<BR>
<BR>
<DT CLASS="dt-description"><B>?T1 #&lt; ?T2</B><DD CLASS="dd-description">
<A NAME="@default60"></A>
The value of the rational term <I>T1</I> is less than the value of the
rational term <I>T2</I>.<BR>
<BR>
<DT CLASS="dt-description"><B>?T1 #&lt;= ?T2</B><DD CLASS="dd-description">
<A NAME="@default61"></A>
The value of the rational term <I>T1</I> is less than or equal to the value of the
rational term <I>T2</I>.<BR>
<BR>
<DT CLASS="dt-description"><B>?T1 #= ?T2</B><DD CLASS="dd-description">
<A NAME="@default62"></A>
The value of the rational term <I>T1</I> is equal to the
value of the rational term <I>T2</I>.<BR>
<BR>
<DT CLASS="dt-description"><B>?T1 #&gt; ?T2</B><DD CLASS="dd-description">
<A NAME="@default63"></A>
The value of the rational term <I>T1</I> is greater than the
value of the rational term <I>T2</I>.<BR>
<BR>
<DT CLASS="dt-description"><B>?T1 #&gt;= ?T2</B><DD CLASS="dd-description">
<A NAME="@default64"></A>
The value of the rational term <I>T1</I> is greater than or equal to the
value of the rational term <I>T2</I>.</DL>
<A NAME="toc4"></A>
<H2 CLASS="section"><A NAME="htoc6">2.4</A>&nbsp;&nbsp;Logical Constraint Predicates</H2>
The logical constraints can be used to combine simpler constraints
and to build complex logical constraint expressions.
These constraints are preprocessed by the system and transformed
into a sequence of evaluation constraints and arithmetic constraints.
The logical operators are declared with the following precedences:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
:- op(750, fy, #\+).
:- op(760, yfx, #/\).
:- op(770, yfx, #\/).
:- op(780, yfx, #=&gt;).
:- op(790, yfx, #&lt;=&gt;).
</PRE></BLOCKQUOTE>
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description"><B>#\+ +E1</B><DD CLASS="dd-description">
<A NAME="@default65"></A>
<I>E1</I> is false, i.e. the logical negation of the constraint
expression <I>E1</I> is imposed.<BR>
<BR>
<DT CLASS="dt-description"><B>+E1 #/\+E2</B><DD CLASS="dd-description">
<A NAME="@default66"></A>
Both constraint expressions <I>E1</I> and <I>E2</I> are true.
This is equivalent to normal conjunction <I>(E1, E2)</I>.<BR>
<BR>
<DT CLASS="dt-description"><B>+E1 #\/+E2</B><DD CLASS="dd-description">
<A NAME="@default67"></A>
At least one of constraint expressions <I>E1</I> and <I>E2</I> is true.
As soon as one of <I>E1</I> or <I>E2</I> becomes false, the other constraint
is imposed.<BR>
<BR>
<DT CLASS="dt-description"><B>+E1 #=&gt; +E2</B><DD CLASS="dd-description">
<A NAME="@default68"></A>
The constraint expression <I>E1</I> implies the
constraint expression <I>E2</I>.
If <I>E1</I> becomes true, then <I>E2</I> is imposed.
If <I>E2</I> becomes false, then the negation of <I>E1</I>
will be imposed.<BR>
<BR>
<DT CLASS="dt-description"><B>+E1 #&lt;=&gt; +E2</B><DD CLASS="dd-description">
<A NAME="@default69"></A>
The constraint expression <I>E1</I> is equivalent to the
constraint expression <I>E2</I>.
If one expression becomes true, the other one will be imposed.
If one expression becomes false, the negation of the other one will be imposed.
</DL>
<A NAME="toc5"></A>
<H2 CLASS="section"><A NAME="htoc7">2.5</A>&nbsp;&nbsp;Evaluation Constraint Predicates</H2>
These constraint predicates evaluate the given constraint expression
and associate its truth value with a boolean variable.
They can be very useful for defining more complex constraints.
They can be used both to test entailment of a constraint
and to impose a constraint or its negation on the current constraint store.
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<B>?B isd +Expr</B><DD CLASS="dd-description">
<A NAME="@default70"></A>
<I>B</I> is equal to 1 iff
the constraint expression <I>Expr</I> is true, 0 otherwise.
This predicate is the constraint counterpart of <A HREF="../bips/kernel/arithmetic/is-2.html"><B>is/2</B></A><A NAME="@default71"></A> &mdash;
it takes a constraint expression, transforms all its subexpressions
into calls to predicates with arity one higher and combines
the resulting boolean values to yield <I>B</I>.
For instance,
<BLOCKQUOTE CLASS="quote">
<B>B isd X #= Y</B>
</BLOCKQUOTE>
is equivalent to
<BLOCKQUOTE CLASS="quote">
<B>#=(X, Y, B)</B>
</BLOCKQUOTE><BR>
<BR>
<DT CLASS="dt-description"><B>#&lt;(?T1, ?T2, ?B)</B><DD CLASS="dd-description">
<A NAME="@default72"></A>
<I>B</I> is equal to 1 iff
the value of the rational term <I>T1</I> is less than the value of the
rational term <I>T2</I>, 0 otherwise.<BR>
<BR>
<DT CLASS="dt-description"><B>#&lt;=(?T1, ?T2, ?B)</B><DD CLASS="dd-description">
<A NAME="@default73"></A>
<I>B</I> is equal to 1 iff
the value of the rational term <I>T1</I> is less than or equal to the value of the
rational term <I>T2</I>, 0 otherwise.<BR>
<BR>
<DT CLASS="dt-description"><B>#=(?T1, ?T2, ?B)</B><DD CLASS="dd-description">
<A NAME="@default74"></A>
<I>B</I> is equal to 1 iff
the value of the rational term <I>T1</I> is equal to the
value of the rational term <I>T2</I>, 0 otherwise.<BR>
<BR>
<DT CLASS="dt-description"><B>#\=(?T1, ?T2, ?B)</B><DD CLASS="dd-description">
<A NAME="@default75"></A>
<I>B</I> is equal to 1 iff
the value of the rational term <I>T1</I> is different from the
value of the rational term <I>T2</I>, 0 otherwise.<BR>
<BR>
<DT CLASS="dt-description"><B>#&gt;(?T1, ?T2, ?B)</B><DD CLASS="dd-description">
<A NAME="@default76"></A>
<I>B</I> is equal to 1 iff
the value of the rational term <I>T1</I> is greater than the
value of the rational term <I>T2</I>, 0 otherwise.<BR>
<BR>
<DT CLASS="dt-description"><B>#&gt;=(?T1, ?T2, ?B)</B><DD CLASS="dd-description">
<A NAME="@default77"></A>
<I>B</I> is equal to 1 iff
the value of the rational term <I>T1</I> is greater than or equal to the
value of the rational term <I>T2</I>, 0 otherwise.<BR>
<BR>
<DT CLASS="dt-description"><B>#/\(+E1, +E2, ?B)</B><DD CLASS="dd-description">
<A NAME="@default78"></A>
<I>B</I> is equal to 1 iff
both constraint expressions <I>E1</I> and <I>E2</I> are true,
0 otherwise.<BR>
<BR>
<DT CLASS="dt-description"><B>#\/(+E1, +E2, ?B)</B><DD CLASS="dd-description">
<A NAME="@default79"></A>
<I>B</I> is equal to 1 iff
at least one of the constraint expressions <I>E1</I> and <I>E2</I> is true,
0 otherwise.<BR>
<BR>
<DT CLASS="dt-description"><B>#&lt;=&gt;(+E1, +E2, ?B)</B><DD CLASS="dd-description">
<A NAME="@default80"></A>
<I>B</I> is equal to 1 iff
the constraint expression <I>E1</I> is equivalent to the
constraint expression <I>E2</I>,
0 otherwise.<BR>
<BR>
<DT CLASS="dt-description"><B>#=&gt;(+E1, +E2, ?B)</B><DD CLASS="dd-description">
<A NAME="@default81"></A>
<I>B</I> is equal to 1 iff
the constraint expression <I>E1</I> implies the
constraint expression <I>E2</I>,
0 otherwise.<BR>
<BR>
<DT CLASS="dt-description"><B>#\+(+E1, ?B)</B><DD CLASS="dd-description">
<A NAME="@default82"></A>
<I>B</I> is equal to 1 iff
<I>E1</I> is false,
0 otherwise.</DL>
<A NAME="toc6"></A>
<H2 CLASS="section"><A NAME="htoc8">2.6</A>&nbsp;&nbsp;CHIP Compatibility Constraints Predicates</H2>
These constraints, defined in the module <B>fd_chip</B>,
are provided for CHIP v.3 compatibility and they are defined using
<A NAME="@default83"></A>
native ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> constraints.
Their source is available in the file <B>fd_chip.pl</B>.
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<B>?T1 ## ?T2</B><DD CLASS="dd-description">
<A NAME="@default84"></A>
The value of the rational term <I>T1</I> is not equal to the value of the
rational term <I>T2</I>.<BR>
<BR>
<DT CLASS="dt-description"><B>alldistinct(?List)</B><DD CLASS="dd-description">
<A NAME="@default85"></A>
All elements of <I>List</I> (domain variables and ground terms) are pairwise
different.<BR>
<BR>
<DT CLASS="dt-description"><B>deleteff(?Var, +List, -Rest)</B><DD CLASS="dd-description">
<A NAME="@default86"></A>
This predicate is used to select a variable from a list of domain variables
which has the smallest domain.
<I>Var</I> is the selected variable from <I>List</I>,
<I>Rest</I> is the rest of the list without <I>Var</I>.<BR>
<BR>
<DT CLASS="dt-description"><B>deleteffc(?Var, +List, -Rest)</B><DD CLASS="dd-description">
<A NAME="@default87"></A>
This predicate is used to select the most constrained variable from a list
of domain variables.
<I>Var</I> is the selected variable from <I>List</I> which has the least domain
and which has the most constraints attached to it.
<I>Rest</I> is the rest of the list without <I>Var</I>.<BR>
<BR>
<DT CLASS="dt-description"><B>deletemin(?Var, +List, -Rest)</B><DD CLASS="dd-description">
<A NAME="@default88"></A>
This predicate is used to select the domain variable with the smallest
lower domain bound from a list of domain variables.
<I>Var</I> is the selected variable from <I>List</I>,
<I>Rest</I> is the rest of the list without <I>Var</I>.<BR>
<BR>
<I>List</I> is a list of domain variables or integers. Integers are treated
as if they were variables with singleton domains.<BR>
<BR>
<DT CLASS="dt-description"><B>dom(+DVar, -List)</B><DD CLASS="dd-description">
<A NAME="@default89"></A>
<I>List</I> is the list of elements in the domain of the domain variable
<I>DVar</I>.
The predicate <B>::/2</B> can also be used to query the domain
of a domain variable, however it yields a list of intervals.<BR>
<BR>
<B>NOTE:</B> This predicate 
should not be used in ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> programs, because all intervals
in the domain will be expanded into element lists which causes
unnecessary space and time overhead.
Unless an explicit list representation is required, finite
domains should be processed by the family of the <B>dom_*</B>
predicates in sections <A HREF="#domaccess">2.14.2</A> and <A HREF="#dommodify">2.14.3</A>.<BR>
<BR>
<DT CLASS="dt-description"><B>maxdomain(+DVar, -Max)</B><DD CLASS="dd-description">
<A NAME="@default90"></A>
<I>Max</I> is the maximum value in the domain of the integer domain
variable <I>DVar</I>.<BR>
<BR>
<DT CLASS="dt-description"><B>mindomain(+DVar, -Min)</B><DD CLASS="dd-description">
<A NAME="@default91"></A>
<I>Min</I> is the minimum value in the domain of the integer domain
variable <I>DVar</I>.</DL>
<A NAME="toc7"></A>
<H2 CLASS="section"><A NAME="htoc9">2.7</A>&nbsp;&nbsp;Utility Constraints Predicates</H2>
These constraints are defined in the module <B>fd_util</B>
and they consist of useful predicates that are often
needed in constraint programs.
Their source code is available in the file <B>fd_util.pl</B>.
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<B>#(?Min, ?CstList, ?Max)</B><DD CLASS="dd-description">
<A NAME="@default92"></A>
The cardinality operator.
<I>CstList</I> is a list of constraint expressions and this operator
states that at least <I>Min</I> and at most <I>Max</I> out of them
are valid.<BR>
<BR>
<DT CLASS="dt-description"><B>dvar_domain_list(?Var, ?List)</B><DD CLASS="dd-description">
<A NAME="@default93"></A>
<I>List</I> is the list of elements in the domain of the domain variable
or ground term <I>DVar</I>.
The predicate <B>::/2</B> can also be used to query the domain
of a domain variable, however it yields a list of intervals.<BR>
<BR>
<DT CLASS="dt-description"><B>outof(?Var, +List)</B><DD CLASS="dd-description">
<A NAME="@default94"></A>
The domain variable <I>Var</I> is different from all elements
of the list <I>List</I>.<BR>
<BR>
<DT CLASS="dt-description"><B>labeling(+List)</B><DD CLASS="dd-description">
<A NAME="@default95"></A>
<A NAME="@default96"></A>
The elements of the <I>List</I> are instantiated using the
<A HREF="../bips/lib/fd/indomain-1.html"><B>indomain/1</B></A><A NAME="@default97"></A> predicate.</DL>
<A NAME="toc8"></A>
<H2 CLASS="section"><A NAME="htoc10">2.8</A>&nbsp;&nbsp;Search Methods</H2>
A library of different search methods for finite domain problems
is available as
<A HREF="../bips/lib/fd_search/index.html"><B>library(fd_search)</B></A><A NAME="@default98"></A>.
See the Reference Manual for details.<BR>
<BR>
<A NAME="toc9"></A>
<H2 CLASS="section"><A NAME="htoc11">2.9</A>&nbsp;&nbsp;Domain Output</H2>
The library <B>fd_domain.pl</B> contains output macros which
cause an <B>fd</B> attribute as well as a domain to be printed
as lists that represent the domain values.
A domain variable is an attributed variable whose <B>fd</B> attribute
has a <B>print</B> handler which prints it in the same format.
For instance,
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
[eclipse 4]: X::1..10, dvar_attribute(X, A), A = fd{domain:D}.

X = X{[1..10]}
D = [1..10]
A = [1..10]
yes.
[eclipse 5]: A::1..10, printf("%mw", A).
A{[1..10]}
A = A{[1..10]}
yes.
</PRE></BLOCKQUOTE>
<A NAME="toc10"></A>
<H2 CLASS="section"><A NAME="htoc12">2.10</A>&nbsp;&nbsp;Debugging Constraint Programs</H2>
The ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> debugger is a low-level debugger which is
suitable only to debug small constraint programs or to debug
small parts of larger programs. Typically, one would use this debugger
to debug user-defined constraints and Prolog data processing.
When they are known to work properly, this debugger may
not be helpful enough to find bugs (correctness debugging) or to speed up 
a working program (performance debugging).
For this, the <B>display_matrix</B> tool from tkeclipse may be the
appropriate tool. <BR>
<BR>
<A NAME="toc11"></A>
<H2 CLASS="section"><A NAME="htoc13">2.11</A>&nbsp;&nbsp;Debugger Support</H2>
The ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP> debugger supports
debugging and tracing of finite domain programs in various ways.
First of all, the debugger commands that handle suspended
goals can be used to display suspended constraints (<B>d</B>, <CODE><B>^</B></CODE>,
<B>u</B>) or
to skip to a particular constraint (<B>w</B>, <B>i</B>).
Note that most of the constraints are displayed using a write macro,
<A NAME="@default99"></A>
their internal form is different. <BR>
<BR>
Successive updates of a domain variable can be traced using the
debug event <B>Hd</B>.
When used, the debugger prompts for a variable name and then it
skips to the port at which the domain of this variable
was reduced.
When a newline is typed instead of a variable name, it skips
to the update of the previously entered variable.<BR>
<BR>
A sequence of woken goals can be skipped using the debug event <B>Hw</B>.
<A NAME="@default100"></A><BR>
<BR>
<A NAME="toc12"></A>
<H2 CLASS="section"><A NAME="htoc14">2.12</A>&nbsp;&nbsp;Examples</H2>
A very simple example of using the finite domains is the <I>send
more money</I> puzzle:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">

:- use_module(library(fd)).

send(List) :-
    List = [S, E, N, D, M, O, R, Y],
    List :: 0..9,
    alldifferent(List),
    1000*S+100*E+10*N+D + 1000*M+100*O+10*R+E #=
        10000*M+1000*O+100*N+10*E+Y,
    M #\= 0,
    S #\= 0,
    labeling(List).
</PRE></BLOCKQUOTE>
The problem is stated very simply, one just writes down the conditions
that must hold for the involved variables and then uses the default
<I>labeling</I> procedure, i.e. the order in which the variables
<A NAME="@default101"></A>
will be instantiated.
When executing <B>send/1</B>, the variables <I>S</I>, <I>M</I>
and <I>O</I> are instantiated even before the labeling
procedure starts.
When a consistent value for the variable <I>E</I> is found (5),
and this value is propagated to the other variables, all
variables become instantiated and thus the rest of the labeling
procedure only checks groundness of the list.<BR>
<BR>
A slightly more elaborate example is the <I>eight queens</I>
puzzle.
Let us show a solution for this problem generalised to N queens
and also enhanced by a cost function that evaluates
every solution.
The cost can be for example
 <I>coli - rowi</I> 
for the i-th queen.
We are now looking for the solution with the smallest cost,
i.e. one for which the maximum of all
<I>coli - rowi</I> 
is minimal:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
:- use_module(library(fd)).

% Find the minimal solution for the N-queens problem
cqueens(N, List) :-
    make_list(N, List),
    List :: 1..N,
    constrain_queens(List),
    make_cost(1, List, C),
    min_max(labeling(List), C).

% Set up the constraints for the queens
constrain_queens([]).
constrain_queens([X|Y]) :-
    safe(X, Y, 1),
    constrain_queens(Y).

safe(_, [], _).
safe(X, [Y|T], K) :-
    noattack(X, Y, K) ,
    K1 is K + 1 ,
    safe(X, T, K1).

% Queens in rows X and Y cannot attack each other
noattack(X, Y, K) :-
    X #\= Y,
    X + K #\= Y,
    X - K #\= Y.

% Create a list with N variables
make_list(0, []) :- !.
make_list(N, [_|Rest]) :-
    N1 is N - 1,
    make_list(N1, Rest).

% Set up the cost expression
make_cost(_, [], []).
make_cost(N, [Var|L], [N-Var|Term]) :-
    N1 is N + 1,
    make_cost(N1, L, Term).

labeling([]) :- !.
labeling(L) :-
    deleteff(Var, L, Rest),
    indomain(Var),
    labeling(Rest).
</PRE></BLOCKQUOTE>
The approach is similar to the previous example: first we create
the domain variables, one for each column of the board,
whose values will be the rows.
We state constraints which must hold between every pair
of queens and finally
we make the cost term in the format required for the
<A HREF="../bips/lib/fd/min_max-2.html"><B>min_max/2</B></A><A NAME="@default102"></A> predicate.
The labeling predicate selects the most constrained variable
for instantiation using the <A HREF="../bips/lib/fd/deleteff-3.html"><B>deleteff/3</B></A><A NAME="@default103"></A> predicate.
When running the example, we get the following result:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
[eclipse 19]: cqueens(8, X).
Found a solution with cost 5
Found a solution with cost 4

X = [5, 3, 1, 7, 2, 8, 6, 4] 
yes.
</PRE></BLOCKQUOTE>
The time needed to find the minimal solution is about five times
shorter than the time to generate all solutions.
This shows the advantage of the <I>branch and bound</I> method.
Note also that the board for this `minimal' solution looks
very nice.<BR>
<BR>
<A NAME="toc13"></A>
<H2 CLASS="section"><A NAME="htoc15">2.13</A>&nbsp;&nbsp;General Guidelines to the Use of Domains</H2>
The <I>send more money</I> example already shows the general
principle of solving problems
using finite domain constraints:
<UL CLASS="itemize"><LI CLASS="li-itemize">
First the variables are defined and their domains are specified.<BR>
<BR>
<LI CLASS="li-itemize">Then the constraints are imposed on these variables.
In the above example the constraints are simply built-in predicates.
For more complicated problems it is often necessary to define
Prolog predicates that process the variables and impose constraints
on them.<BR>
<BR>
<LI CLASS="li-itemize">If stating the constraints alone did not solve the problem,
one tries to assign values to the variables. Since every
instantiation immediately wakes all constraints associated with the variable,
and changes are propagated to the other variables, the search space
is usually quickly reduced and either an early failure occurs
or the domains of other variables are reduced or directly instantiated.
This labeling procedure is therefore incomparably more efficient
<A NAME="@default104"></A>
than the simple <I>generate and test</I> algorithm.
</UL>
The complexity of the program and the efficiency of the solving
depends very much on the way these three points are performed.
Quite frequently it is possible to state the same problem
using different sets of variables with different domains.
A guideline is that the search space should be as small as possible,
and thus e.g. five variables with domain 1..10
(i.e. search space size is 10<SUP>5</SUP>)
are likely to be better than
twenty variables with domain 0..1
(space size 2<SUP>20</SUP>).<BR>
<BR>
The choice of constraints is also very important.
Sometimes a redundant constraint, i.e. one that follows from the
other constraints, can speed up the search considerably.
This is because the system does not propagate <I>all</I>
information it has to all concerned variables, because
most of the time this would not bring anything, and thus it would
slow down the search.
Another reason is that the library performs no meta-level reasoning on
constraints themselves (unlike the <FONT COLOR=purple>CHR</FONT> library).
For example, the constraints
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
X + Y #= 10, X + Y + Z #= 14
</PRE></BLOCKQUOTE>
allow only the value 4 for <I>Z</I>, however the system is not
able to deduce this and thus it has to be provided
as a redundant constraint.<BR>
<BR>
The constraints should be stated in such a way that allows the system
to propagate all important domain updates to the appropriate variables.<BR>
<BR>
Another rule of thumb is that creation of choice points should be delayed
as long as possible. Disjunctive constraints, if there are any,
should be postponed as much as possible. Labeling, i.e. value
choosing, should be done after all deterministic operations
are carried out.<BR>
<BR>
The choice of the labeling procedure is perhaps the most
<A NAME="@default105"></A>
sensitive one.
It is quite common that only a very minor change in the order
of instantiated variables can speed up or slow down the search
by several orders of magnitude.
There are very few common rules available.
If the search space is large, it usually pays off to spend
more time in selecting the next variable to instantiate.
The provided predicates <A HREF="../bips/lib/fd/deleteff-3.html"><B>deleteff/3</B></A><A NAME="@default106"></A> and <A HREF="../bips/lib/fd/deleteffc-3.html"><B>deleteffc/3</B></A><A NAME="@default107"></A>
can be used to select the most constrained variable, but in
many problems it is possible to extract even more information
about which variable to instantiate next.<BR>
<BR>
Often it is necessary to try out several approaches
and see how they work, if they do.
The profiler and the statistics package can be of a great help here,
it can point to predicates which are executed too often, or
choice points unnecessarily backtracked over.<BR>
<BR>
<A NAME="toc14"></A>
<H2 CLASS="section"><A NAME="htoc16">2.14</A>&nbsp;&nbsp;User-Defined Constraints</H2>
The <B>fd.pl</B> library defines a set of low-level predicates
which
allow the user to process domain variables
and their domains, modify them and write new constraint
predicates.<BR>
<BR>

<H3 CLASS="subsection"><A NAME="htoc17">2.14.1</A>&nbsp;&nbsp;The <I>fd</I> Attribute</H3>
A domain variable is a metaterm.
<A NAME="@default108"></A>
<A NAME="@default109"></A>
The <B>fd.pl</B> library defines a metaterm attribute
<BLOCKQUOTE CLASS="quote">
<B><I>fd</I>{<I>domain</I>:<I>D</I>, <I>min</I>:<I>Mi</I>, <I>max</I>:<I>Ma</I>, <I>any</I>:<I>A</I>}</B>
</BLOCKQUOTE>
<A NAME="fd:attribute"></A>
which stores the domain information together with several suspension lists.
The attribute arguments have the following meaning:
<UL CLASS="itemize"><LI CLASS="li-itemize">
<B>domain</B> - the representation of the domain itself.
Domains are treated as abstract data types, the users should not
access them directly, but only using access and modification
predicates listed below.<BR>
<BR>
<LI CLASS="li-itemize"><B>min</B> - a suspension list that should be woken when the minimum
 of the domain is updated<BR>
<BR>
<LI CLASS="li-itemize"><B>max</B> - a suspension list that should be woken when the maximum
 of the domain is updated<BR>
<BR>
<LI CLASS="li-itemize"><B>any</B> - a suspension list that should be woken when the domain
 is reduced no matter how.
</UL>
The suspension list names can be used in the predicate <A HREF="../bips/kernel/suspensions/suspend-3.html"><B>suspend/3</B></A><A NAME="@default110"></A>
to denote an appropriate waking condition.<BR>
<BR>
The attribute of a domain variable can be accessed
with the predicate <A HREF="../bips/lib/fd/dvar_attribute-2.html"><B>dvar_attribute/2</B></A><A NAME="@default111"></A>
or by unification in a matching clause:
<A NAME="@default112"></A>
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
get_attribute(_{fd:Attr}, A) :-
    -?-&gt;
    Attr = A.
</PRE></BLOCKQUOTE>
Note however, that this matching clause succeeds even if the first
argument is a metaterm but its <B>fd</B> attribute is empty.
To succeed only for domain variables, the clause
must be
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
get_attribute(_{fd:Attr}, A) :-
    -?-&gt;
    nonvar(Attr),
    Attr = A.
</PRE></BLOCKQUOTE>
or to access directly attribute arguments, e.g. the domain
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
get_domain(_{fd:fd{domain:D}}, Dom) :-
    -?-&gt;
    D = Dom.
</PRE></BLOCKQUOTE>
The <A HREF="../bips/lib/fd/dvar_attribute-2.html"><B>dvar_attribute/2</B></A><A NAME="@default113"></A> has the advantage that it returns
an attribute-like structure even if its argument is already
instantiated, which is quite useful when coding <B>fd</B>
constraints.<BR>
<BR>
The attribute arguments can be accessed by macros from
the <B>structures.pl</B> library,
if e.g. <B>Attr</B> is the attribute of a domain variable, the max
list can be obtained as
<BLOCKQUOTE CLASS="quote">
arg(max of fd, Attr, Max)
</BLOCKQUOTE>
or, using a unification
<BLOCKQUOTE CLASS="quote">
Attr = fd{max:Max}
</BLOCKQUOTE>

<H3 CLASS="subsection"><A NAME="htoc18">2.14.2</A>&nbsp;&nbsp;Domain Access</H3>
<A NAME="domaccess"></A>
The domains are represented as abstract data types, the users are not
supposed to access them directly, instead a number of
predicates and macros are available to allow operations on domains.
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<B>dom_check_in(+Element, +Dom)</B><DD CLASS="dd-description">
<A NAME="@default114"></A>
Succeed if the integer <I>Element</I> is in the domain <I>Dom</I>.<BR>
<BR>
<DT CLASS="dt-description"><B>dom_compare(?Res, +Dom1, +Dom2)</B><DD CLASS="dd-description">
<A NAME="@default115"></A>
Works like <A HREF="../bips/kernel/termcomp/compare-3.html"><B>compare/3</B></A><A NAME="@default116"></A> for terms.
<I>Res</I> is unified with
<UL CLASS="itemize"><LI CLASS="li-itemize">
<B>=</B>
iff <I>Dom1</I> is equal to <I>Dom2</I>,
<LI CLASS="li-itemize"><B>&lt;</B>
iff <I>Dom1</I> is a proper subset of <I>Dom2</I>,
<LI CLASS="li-itemize"><B>&gt;</B>
iff <I>Dom2</I> is a proper subset of <I>Dom1</I>.
</UL>
Fails if neither domain is a subset of the other one.<BR>
<BR>
<DT CLASS="dt-description"><B>dom_member(?Element, +Dom)</B><DD CLASS="dd-description">
<A NAME="@default117"></A>
Successively instantiate <I>Element</I> to the values in the domain <I>Dom</I>
(similar to <A HREF="../bips/lib/fd/indomain-1.html"><B>indomain/1</B></A><A NAME="@default118"></A>).<BR>
<BR>
<DT CLASS="dt-description"><B>dom_range(+Dom, ?Min, ?Max)</B><DD CLASS="dd-description">
<A NAME="@default119"></A>
Return the minimum and maximum value in the integer domain <I>Dom</I>.
Fails if <I>Dom</I> is a domain containing non-integer 
elements.
This predicate can also be used to test if a given domain
is integer or not.<BR>
<BR>
<DT CLASS="dt-description"><B>dom_size(+Dom, ?Size)</B><DD CLASS="dd-description">
<A NAME="@default120"></A>
<I>Size</I> is the number of elements in the domain <I>Dom</I>.</DL>

<H3 CLASS="subsection"><A NAME="htoc19">2.14.3</A>&nbsp;&nbsp;Domain Operations</H3>
<A NAME="dommodify"></A>
The following predicates operate on domains alone, without modifying
domain <I>variables</I>.
Most of them return the size of the resulting domain which can be used
to test if any modification was done.
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<B>dom_copy(+Dom1, -Dom2)</B><DD CLASS="dd-description">
<A NAME="@default121"></A>
<I>Dom2</I> is a copy of the domain <I>Dom1</I>.
Since the updates are done in-place, two domain variables must not share
the same physical domain and so when defining a new variable
with an existing domain, the domain has to be copied first.<BR>
<BR>
<DT CLASS="dt-description"><B>dom_difference(+Dom1, +Dom2, -DomDiff, ?Size)</B><DD CLASS="dd-description">
<A NAME="@default122"></A>
The domain <I>DomDifference</I> is
<I>Dom1 \ Dom2</I>
and <I>Size</I> is the number of its elements.
Fails if <I>Dom1</I> is a subset of <I>Dom2</I>.<BR>
<BR>
<DT CLASS="dt-description"><B>dom_intersection(+Dom1, +Dom2, -DomInt, ?Size)</B><DD CLASS="dd-description">
<A NAME="@default123"></A>
The domain <I>DomInt</I> is the intersection of domains
<I>Dom1</I> and <I>Dom2</I> and <I>Size</I> is the number of its elements.
Fails if the intersection is empty.<BR>
<BR>
<DT CLASS="dt-description"><B>dom_union(+Dom1, +Dom2, -DomUnion, ?Size)</B><DD CLASS="dd-description">
<A NAME="@default124"></A>
The domain <I>DomUnion</I> is the union of domains
<I>Dom1</I> and <I>Dom2</I> and <I>Size</I> is the number of its elements.
Note that the main use of the predicate is to yield
the most specific generalisation of two domains, in the usual cases
the domains become smaller, not bigger.<BR>
<BR>
<DT CLASS="dt-description"><B>list_to_dom(+List, -Dom)</B><DD CLASS="dd-description">
<A NAME="@default125"></A>
Convert a list of ground terms and integer intervals into
a domain <I>Dom</I>.
It does not have to be sorted and integers and intervals
may overlap.<BR>
<BR>
<DT CLASS="dt-description"><B>integer_list_to_dom(+List, -Dom)</B><DD CLASS="dd-description">
<A NAME="@default126"></A>
Similar to <A HREF="../bips/lib/fd/list_to_dom-2.html"><B>list_to_dom/2</B></A><A NAME="@default127"></A> <A NAME="@default128"></A>, but the input list should
contain only integers and integer intervals and it should be sorted.
This predicate will merge adjacent integers and intervals
into larger intervals whenever possible.
typically, this predicate should be used to convert
a sorted list of integers into a finite domain.
If the list is known to already contain proper intervals,
<A HREF="../bips/lib/fd/sorted_list_to_dom-2.html"><B>sorted_list_to_dom/2</B></A><A NAME="@default129"></A> could be used instead.<BR>
<BR>
<DT CLASS="dt-description"><B>sorted_list_to_dom(+List, -Dom)</B><DD CLASS="dd-description">
<A NAME="@default130"></A>
Similar to <A HREF="../bips/lib/fd/list_to_dom-2.html"><B>list_to_dom/2</B></A><A NAME="@default131"></A>, <A NAME="@default132"></A> but the input list is assumed
to be already in the correct format, i.e. sorted and with correct integer
and interval values.
No checking on the list contents is performed.</DL>

<H3 CLASS="subsection"><A NAME="htoc20">2.14.4</A>&nbsp;&nbsp;Accessing Domain Variables</H3>
The following predicates perform various operations:
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<B>dvar_attribute(+DVar, -Attrib)</B><DD CLASS="dd-description">
<A NAME="@default133"></A>
<I>Attrib</I> is the attribute of the domain variable <I>DVar</I>.
If <I>DVar</I> is instantiated, <I>Attrib</I> is bound to an attribute
with a singleton domain and empty suspension lists.<BR>
<BR>
<DT CLASS="dt-description"><B>dvar_domain(+DVar, -Dom)</B><DD CLASS="dd-description">
<A NAME="@default134"></A>
<I>Dom</I> is the domain of the domain variable <I>DVar</I>.
If <I>DVar</I> is instantiated, <I>Dom</I> is bound to
a singleton domain.<BR>
<BR>
<DT CLASS="dt-description"><B>var_fd(?Var, +Dom)</B><DD CLASS="dd-description">
<A NAME="@default135"></A>
If <I>Var</I> is a free variable,
it becomes a domain variable with the domain <I>Dom</I>
and with empty suspension lists.
The domain <I>Dom</I> is copied to make in-place updates
logically sound.
If <I>Var</I> is already a domain variable, its domain is intersected
with the domain <I>Dom</I>.
Fails if <I>Var</I> is not a variable.<BR>
<BR>
<DT CLASS="dt-description"><B>dvar_msg(+DVar1, +DVar2, -MsgDVar)</B><DD CLASS="dd-description">
<A NAME="@default136"></A>
<I>MsgVar</I> is a domain variable which is the most specific generalisation
of domain variables or ground values <I>Var1</I> and <I>Var2</I>.</DL>

<H3 CLASS="subsection"><A NAME="htoc21">2.14.5</A>&nbsp;&nbsp;Modifying Domain Variables</H3>
When the domain of a domain variable is reduced, some suspension
lists stored in the attribute have to be scheduled and woken.<BR>
<BR>
<B>NOTE:</B> In the <B>fd.pl</B> library the suspension lists
are woken precisely when the event associated with the
list occurs.
Thus e.g. the <B>min</B> list is woken if and only if the minimum
value of the variable's domain is changed, but it is not
woken when the variable is instantiated to this minimum
or when another element from the domain is removed.
In this way, user-defined constraints can rely on the fact that
when they are executed, the domain was updated in the expected way.
On the other hand, user-defined constraints should also comply
with this rule and they should take care not to wake lists
when their waking condition did not occur.
Most predicates in this section actually do all the work themselves
so that the user predicates may ignore scheduling and waking completely.
<DL CLASS="description" COMPACT=compact><DT CLASS="dt-description">
<B>dvar_remove_element(+DVar, +El)</B><DD CLASS="dd-description">
<A NAME="@default137"></A>
The element <I>El</I> is removed from the domain of <I>DVar</I> and all
concerned lists are woken.
If the resulting domain is empty, this predicate fails. If it is
a singleton, <I>DVar</I> is instantiated.
If the domain does not contain the element,
no updates are made.<BR>
<BR>
<DT CLASS="dt-description"><B>dvar_remove_smaller(+DVar, +El)</B><DD CLASS="dd-description">
<A NAME="@default138"></A>
Remove all elements in the domain of <I>DVar</I> which are smaller than
the integer <I>El</I> and wake all concerned lists.
If the resulting domain is empty, this predicate fails; if it is
a singleton, <I>DVar</I> is instantiated.<BR>
<BR>
<DT CLASS="dt-description"><B>dvar_remove_greater(+DVar, +El)</B><DD CLASS="dd-description">
<A NAME="@default139"></A>
Remove all elements in the domain of <I>DVar</I> which are greater than
the integer <I>El</I> and wake all concerned lists.
If the resulting domain is empty, this predicate fails; if it is
a singleton, <I>DVar</I> is instantiated.<BR>
<BR>
<DT CLASS="dt-description"><B>dvar_update(+DVar, +NewDom)</B><DD CLASS="dd-description">
<A NAME="@default140"></A>
If the size of the domain <I>NewDom</I> is 0, the predicate fails.
If it is 1,
the domain variable <I>DVar</I>
is instantiated to the value in the domain.
Otherwise,
if the size of the new domain is smaller than the size of
the domain variable's domain,
the domain of <I>DVar</I> is replaced by <I>NewDom</I>,
the appropriate suspension lists in its attribute are passed
to the waking scheduler and so is the <B>constrained</B> list
in the <B>suspend</B> attribute of the domain variable.
If the size of the new domain is equal to the old one, no
updates and no waking is done, i.e. this predicate does not
check an explicit equality of both domains.
If the size of the new domain is greater than the old one,
an error is raised.<BR>
<BR>
<DT CLASS="dt-description"><B>dvar_replace(+DVar, +NewDom)</B><DD CLASS="dd-description">
<A NAME="@default141"></A>
This predicate is similar to <A HREF="../bips/lib/fd/dvar_update-2.html"><B>dvar_update/2</B></A><A NAME="@default142"></A>, but it
does not propagate the changes, i.e. no waking is done.
If the size of the new domain is 1, <I>DVar</I>
is not instantiated, but it is given this singleton domain.
This predicate is useful for local consistency checks.</DL>
<A NAME="toc15"></A>
<H2 CLASS="section"><A NAME="htoc22">2.15</A>&nbsp;&nbsp;Extensions</H2>
The <B>fd.pl</B> library can be used as a basis for further
extensions.
There are several hooks that make the interfacing easier:
<UL CLASS="itemize"><LI CLASS="li-itemize">
Each time a new domain variable is created, either
in the <B>::/2</B> predicate or by giving it a default domain
in a rational arithmetic expression, the predicate <A HREF="../bips/lib/fd/new_domain_var-1.html"><B>new_domain_var/1</B></A><A NAME="@default143"></A>
is called with the variable as argument.
Its default definition does nothing. To use it,
it is necessary to redefine it, i.e. to recompile it
in the <B>fd</B> module, e.g. using <A HREF="../bips/kernel/compiler/compile-2.html"><B>compile/2</B></A><A NAME="@default144"></A>
or the tool body of <A HREF="../bips/kernel/compiler/compile_term-1.html"><B>compile_term/1</B></A><A NAME="@default145"></A>.<BR>
<BR>
<LI CLASS="li-itemize">Default domains
<A NAME="@default146"></A>
are created in the predicate <A HREF="../bips/lib/fd/default_domain-1.html"><B>default_domain/1</B></A><A NAME="@default147"></A>
<A NAME="@default148"></A>
in the <B>fd</B> module, its default definition is
<BLOCKQUOTE CLASS="quote">
default_domain(Var) :- Var :: -10000000..10000000.
</BLOCKQUOTE>
It is possible to change default domains by redefining
this predicate in the <B>fd</B> module.
</UL>
<A NAME="toc16"></A>
<H2 CLASS="section"><A NAME="htoc23">2.16</A>&nbsp;&nbsp;Example of Defining a New Constraint</H2>
We will demonstrate creation of new constraints on the
following example.
To show that the constraints are not restricted to linear terms,
we can take the constraint
<BLOCKQUOTE CLASS="quote">
<I>X</I><SUP>2</SUP> + <I>Y</I><SUP>2</SUP> &#8804; <I>C</I>.
</BLOCKQUOTE>
Assuming that <I>X</I> and <I>Y</I> are domain variables, we would
like to define such a predicate that will be woken
as soon as one or both variables' domains are updated in such a way that would
require updating the other variable's domain, i.e. updates
that would propagate via this constraint.
For simplicity we assume that <I>X</I> and <I>Y</I> are nonnegative.
We will define the predicate <B>sq(X, Y, C)</B> which will
implement this constraint:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
:- use_module(library(fd)).

% A*A + B*B &lt;= C
sq(A, B, C) :-
    dvar_domain(A, DomA),
    dvar_domain(B, DomB),
    dom_range(DomA, MinA, MaxA),
    dom_range(DomB, MinB, MaxB),
    MiA2 is MinA*MinA,
    MaB2 is MaxB*MaxB,
    (MiA2 + MaB2 &gt; C -&gt;
        NewMaxB is fix(sqrt(C - MiA2)),
        dvar_remove_greater(B, NewMaxB)
    ;
        NewMaxB = MaxB
    ),
    MaA2 is MaxA*MaxA,
    MiB2 is MinB*MinB,
    (MaA2 + MiB2 &gt; C -&gt;
        NewMaxA is fix(sqrt(C - MiB2)),
        dvar_remove_greater(A, NewMaxA)
    ;
        NewMaxA = MaxA
    ),
    (NewMaxA*NewMaxA + NewMaxB*NewMaxB =&lt; C -&gt;
        true
    ;
        suspend(sq(A, B, C), 3, (A, B)-&gt;min)
    ),
    wake.                % Trigger the propagation
</PRE></BLOCKQUOTE>
The steps to be executed when this constraint becomes active,
i.e. when the predicate <B>sq/3</B> is called or woken
are the following:
<OL CLASS="enumerate" type=1><LI CLASS="li-enumerate">
We access the domains of the two variables
using the predicate <A HREF="../bips/lib/fd/dvar_domain-2.html"><B>dvar_domain/2</B></A><A NAME="@default149"></A> and
and obtain their bounds using <A HREF="../bips/lib/fd/dom_range-3.html"><B>dom_range/3</B></A><A NAME="@default150"></A>.
Note that it may happen that one of the two variables is already instantiated,
but these predicates still work as if the variable had a singleton domain.<BR>
<BR>
<LI CLASS="li-enumerate">We check if the maximum of one or the other variable is still
consistent with this constraint, i.e. if there is a value
in the other variable's domain that satisfies the constraint
together with this maximum.<BR>
<BR>
<LI CLASS="li-enumerate">If the maximum value is no longer consistent, we compute
the new maximum of the domain, and then update the domain
so that all values greater than this value are removed
using the predicate <A HREF="../bips/lib/fd/dvar_remove_greater-2.html"><B>dvar_remove_greater/2</B></A><A NAME="@default151"></A>.
This predicate also wakes all concerned suspension lists
and instantiates the variable if its new domain is a singleton.<BR>
<BR>
<LI CLASS="li-enumerate">After checking the updates for both variables we test
if the constraint is now satisfied for all values
in the new domains.
If this is not the case, we have to suspend the predicate
so that it is woken as soon as the minimum of either domain
is changed.
This is done using the predicate <A HREF="../bips/kernel/suspensions/suspend-3.html"><B>suspend/3</B></A><A NAME="@default152"></A>.<BR>
<BR>
<LI CLASS="li-enumerate">The last action is to trigger the execution of all goals that 
are waiting for
the updates we have made.
It is necessary to wake these goals <B>after</B> inserting
the new suspension, otherwise updates made in the
woken goals would not be propagated back to this constraint.
</OL>
Here is what we get:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
[eclipse 20]: [X,Y]::1..10, sq(X, Y, 50).

X = X{[1..7]}
Y = Y{[1..7]}

Delayed goals:
 sq(X{[1..7]}, Y{[1..7]}, 50)
yes.
[eclipse 21]: [X,Y]::1..10, sq(X, Y, 50), X #&gt; 5.

Y = Y{[1..3]}
X = X{[6, 7]}

Delayed goals:
 sq(X{[6, 7]}, Y{[1..3]}, 50)
yes.
[eclipse 22]: [X,Y]::1..10, sq(X, Y, 50), X #&gt; 5, Y #&gt; 1.

X = 6
Y = Y{[2, 3]}
yes.
[eclipse 23]: [X,Y]::1..10, sq(X, Y, 50), X #&gt; 5, Y #&gt; 2.

X = 6
Y = 3
yes.
</PRE></BLOCKQUOTE>
<A NAME="toc17"></A>
<H2 CLASS="section"><A NAME="htoc24">2.17</A>&nbsp;&nbsp;Program Examples</H2>
In this section we present some FD programs that show various
aspects of the library usage.<BR>
<BR>

<H3 CLASS="subsection"><A NAME="htoc25">2.17.1</A>&nbsp;&nbsp;Constraining Variable Pairs</H3>
The finite domain library gives the user the possibility
to impose constraints on the value of a variable.
How, in general, is it possible to impose constraints on two
or more variables?
For example, let us assume that we have a set of colours and we
want to define that some colours fit with each other and others do not.
This should work in such a way as to propagate possible changes
in the domains as soon as this becomes possible.<BR>
<BR>
Let us assume we have a symmetric relation that defines which
colours fit with each other:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
% The basic relation
fit(yellow, blue).
fit(yellow, red).
fit(blue, yellow).
fit(red, yellow).
fit(green, orange).
fit(orange, green).
</PRE></BLOCKQUOTE>
The predicate <B>nice_pair(X, Y)</B> is a constraint and any change of
the possible values of X or Y is propagated
to the other variable.
There are many ways in which this pairing can be defined in ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>.
They are different solutions with different properties, but
they yield the same results.<BR>
<BR>

<H4 CLASS="subsubsection">2.17.1.1&nbsp;&nbsp;User-Defined Constraints</H4>
We use more or less directly the low-level primitives to handle
finite domain variables.
We collect all consistent values for the two variables, remove
all other values from their domains and then suspend
the predicate until one of its arguments is updated:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
nice_pair(A, B) :-
        % get the domains of both variables
    dvar_domain(A, DA),         
    dvar_domain(B, DB),         
        % make a list of respective matching colours
    setof(Y, X^(dom_member(X, DA), fit(X, Y)), BL),
    setof(X, Y^(dom_member(Y, DB), fit(X, Y)), AL),
        % convert the lists to domains
    sorted_list_to_dom(AL, DA1),
    sorted_list_to_dom(BL, DB1),
        % intersect the lists with the original domains
    dom_intersection(DA, DA1, DA_New, _),
    dom_intersection(DB, DB1, DB_New, _),
        % and impose the result on the variables
    dvar_update(A, DA_New),
    dvar_update(B, DB_New),
        % unless one variable is already instantiated, suspend
        % and wake as soon as any element of the domain is removed
    (var(A), var(B) -&gt;
        suspend(nice_pair(A, B), 2, [A,B]-&gt;any)
    ;
        true
    ).

% Declare the domains
colour(A) :-
    findall(X, fit(X, _), L),
    A :: L.
</PRE></BLOCKQUOTE>
After defining the domains, we can state the constraints:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
[eclipse 5]: colour([A,B,C]), nice_pair(A, B), nice_pair(B, C), A #\= green.

B = B{[blue, green, red, yellow]}
C = C{[blue, orange, red, yellow]}
A = A{[blue, orange, red, yellow]}
 
Delayed goals:
  nice_pair(A{[blue, orange, red, yellow]}, B{[blue, green, red, yellow]})
  nice_pair(B{[blue, green, red, yellow]}, C{[blue, orange, red, yellow]})
</PRE></BLOCKQUOTE>
This way of defining new constraints is often the most efficient
one, but usually also the most tedious one.<BR>
<BR>

<H4 CLASS="subsubsection">2.17.1.2&nbsp;&nbsp;Using the <I>element</I> Constraint</H4>
In this case we use the available primitive in the fd library. Whenever
it is necessary to associate a fd variable with some other fd variable,
the <A HREF="../bips/lib/fd/element-3.html"><B>element/3</B></A><A NAME="@default153"></A> constraint is a likely candidate. Sometimes it is
rather awkward to use, because additional variables must be used,
but it gives enough power:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
nice_pair(A, B) :-
    element(I, [yellow, yellow, blue, red, green, orange], A),
    element(I, [blue, red, yellow, yellow, orange, green], B).
</PRE></BLOCKQUOTE>
We define a new variable <B>I</B> which is a sort of index into the
clauses of the fit predicate. The first colour list contains
colours in the first argument of fit/2 and the second list
contains colours from the second argument. The propagation is similar
to that of the previous one.<BR>
<BR>
When <A HREF="../bips/lib/fd/element-3.html"><B>element/3</B></A><A NAME="@default154"></A> can be used, it is usually faster
than the previous approach, because <A HREF="../bips/lib/fd/element-3.html"><B>element/3</B></A><A NAME="@default155"></A> is partly
implemented in C.<BR>
<BR>

<H4 CLASS="subsubsection">2.17.1.3&nbsp;&nbsp;Using Evaluation Constraints</H4>
We can also encode directly the relations between elements
in the domains of the two variables:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
nice_pair(A, B) :-
    np(A, B),
    np(B, A).

np(A, B) :-
    [A,B] :: [yellow, blue, red, orange, green],
    A #= yellow #=&gt; B :: [blue, red],
    A #= blue #=&gt; B #= yellow,
    A #= red #=&gt; B #= yellow,
    A #= green #=&gt; B #= orange,
    A #= orange #=&gt; B #= green.
</PRE></BLOCKQUOTE>
This method is quite simple and does not need any special analysis;
on the other hand it potentially creates a huge number of
auxiliary constraints and variables.<BR>
<BR>

<H4 CLASS="subsubsection">2.17.1.4&nbsp;&nbsp;Using Generalised Propagation</H4>
Propia is the first candidate to convert an existing relation into
a constraint. One can simply use <B>infers most</B> to achieve the propagation:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
nice_pair(A, B) :-
    fit(A, B) infers most.
</PRE></BLOCKQUOTE>
Using Propia is usually very easy and the programs are short
and readable, so that this style of constraints writing
is quite useful e.g. for teaching.
It is not as efficient as with user-defined constraints, but
if the amount of propagation is more important that the efficiency
of the constraint itself, it can yield good results, too.<BR>
<BR>

<H4 CLASS="subsubsection">2.17.1.5&nbsp;&nbsp;Using Constraint Handling Rules</H4>
The <TT>domain</TT> solver in <FONT COLOR=purple>CHR</FONT> can be used directly with the
<A HREF="../bips/lib/fd/element-3.html"><B>element/3</B></A><A NAME="@default156"></A> constraint as well, however it is also possible
to define directly domains consisting of pairs:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
:- lib(chr).
:- chr(lib(domain)).

nice_pair(A, B) :-
    setof(X-Y, fit(X, Y), L),
    A-B :: L.

</PRE></BLOCKQUOTE>
The pairs are then constrained accordingly:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
[eclipse 2]: nice_pair(A, B), nice_pair(B, C), A ne orange.

B = B
C = C
A = A

Constraints:
(9) A_g1484 - B_g1516 :: [blue - yellow, green - orange, red - yellow,
yellow - blue, yellow - red]
(10) A_g1484 :: [blue, green, red, yellow]
(12) B_g1516 - C_g3730 :: [blue - yellow, orange - green, red - yellow,
yellow - blue, yellow - red]
(13) B_g1516 :: [blue, orange, red, yellow]
(14) C_g3730 :: [blue, green, red, yellow]
</PRE></BLOCKQUOTE>

<H3 CLASS="subsection"><A NAME="htoc26">2.17.2</A>&nbsp;&nbsp;Puzzles</H3>
Various kinds of puzzles can be easily solved using finite domains.
We show here the classical Lewis Carrol's puzzle with five houses and a zebra:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
Five men with different nationalities live in the first five houses
of a street.  They practise five distinct professions, and each of
them has a favourite animal and a favourite drink, all of them
different.  The five houses are painted in different colours.

The Englishman lives in a red house.
The Spaniard owns a dog.
The Japanese is a painter.
The Italian drinks tea.
The Norwegian lives in the first house on the left.
The owner of the green house drinks coffee.
The green house is on the right of the white one.
The sculptor breeds snails.
The diplomat lives in the yellow house.
Milk is drunk in the middle house.
The Norwegian's house is next to the blue one.
The violinist drinks fruit juice.
The fox is in a house next to that of the doctor.
The horse is in a house next to that of the diplomat.

Who owns a Zebra, and who drinks water?
</PRE></BLOCKQUOTE>
One may be tempted to define five variables Nationality,
Profession, Colour, etc. with atomic domains to represent
the problem.
Then, however, it is quite difficult to express equalities
over these different domains.
A much simpler solution is to define 5x5 integer variables for each
mentioned item, to number the houses from one to five
and to represent the fact that e.g. Italian drinks tea
by equating Italian = Tea.
The value of both variables represents then the number of their house.
In this way, no special constraints are needed and
the problem is very easily described:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
:- lib(fd).

zebra([zebra(Zebra), water(Water)]) :-
    Sol = [Nat, Color, Profession, Pet, Drink],
    Nat = [English, Spaniard, Japanese, Italian, Norwegian],
    Color = [Red, Green, White, Yellow, Blue],
    Profession = [Painter, Sculptor, Diplomat, Violinist, Doctor],
    Pet = [Dog, Snails, Fox, Horse, Zebra],
    Drink = [Tea, Coffee, Milk, Juice, Water],

    % we specify the domains and the fact
    % that the values are exclusive
    Nat :: 1..5,
    Color :: 1..5,
    Profession :: 1..5,
    Pet :: 1..5,
    Drink :: 1..5,
    alldifferent(Nat),
    alldifferent(Color),
    alldifferent(Profession),
    alldifferent(Pet),
    alldifferent(Drink),

    % and here follow the actual constraints
    English = Red,
    Spaniard = Dog,
    Japanese = Painter,
    Italian = Tea,
    Norwegian = 1,
    Green = Coffee,
    Green #= White + 1,
    Sculptor = Snails,
    Diplomat = Yellow,
    Milk = 3,
    Dist1 #= Norwegian - Blue, Dist1 :: [-1, 1],
    Violinist = Juice,
    Dist2 #= Fox - Doctor, Dist2 :: [-1, 1],
    Dist3 #= Horse - Diplomat, Dist3 :: [-1, 1],

    flatten(Sol, List),
    labeling(List).
</PRE></BLOCKQUOTE>

<H3 CLASS="subsection"><A NAME="htoc27">2.17.3</A>&nbsp;&nbsp;Bin Packing</H3>
In this type of problems the goal is to pack a certain amount of
different things into the minimal number of bins under specific constraints.
Let us solve an example given by Andre Vellino in the Usenet
group comp.lang.prolog, June 93:
<UL CLASS="itemize"><LI CLASS="li-itemize">
There are 5 types of components:<BR>
<BR>
glass, plastic, steel, wood, copper<BR>
<BR>
<LI CLASS="li-itemize">There are three types of bins:<BR>
<BR>
red, blue, green<BR>
<BR>
<LI CLASS="li-itemize">whose capacity constraints are:
<UL CLASS="itemize"><LI CLASS="li-itemize">
red has capacity 3
<LI CLASS="li-itemize">blue has capacity 1
<LI CLASS="li-itemize">green has capacity 4
</UL><BR>
<BR>
<LI CLASS="li-itemize">containment constraints are:
<UL CLASS="itemize"><LI CLASS="li-itemize">
red can contain glass, wood, copper
<LI CLASS="li-itemize">blue can contain glass, steel, copper
<LI CLASS="li-itemize">green can contain plastic, wood, copper
</UL><BR>
<BR>
<LI CLASS="li-itemize">and requirement constraints are (for all bin types):<BR>
<BR>
wood requires plastic<BR>
<BR>
<LI CLASS="li-itemize">Certain component types cannot coexist:
<UL CLASS="itemize"><LI CLASS="li-itemize">
glass exclusive copper
<LI CLASS="li-itemize">copper exclusive plastic
</UL><BR>
<BR>
<LI CLASS="li-itemize">and certain bin types have capacity constraint for certain
components
<UL CLASS="itemize"><LI CLASS="li-itemize">
red contains at most 1 of wood
<LI CLASS="li-itemize">green contains at most 2 of wood
</UL><BR>
<BR>
<LI CLASS="li-itemize">Given an initial supply of:
1 of glass,
2 of plastic,
1 of steel,
3 of wood,
2 of copper,
what is the minimum total number of bins required to
contain the components?
</UL>
To solve this problem, it is not enough to state constraints on some
variables and to start a labeling procedure on them.
The variables are namely not known, because we don't know how many
bins we should take.
One possibility would be to take a large enough number of bins
and to try to find a minimum number.
However, usually it is better to generate constraints
for an increasing fixed number of bins until a solution is found.<BR>
<BR>
The predicate <B>solve/1</B> returns the solution for this
particular problem, <B>solve_bin/2</B> is the general predicate
that takes an amount of components packed into a <B>cont/5</B>
structure and it returns the solution.
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
solve(Bins) :-
    solve_bin(cont(1, 2, 1, 3, 2), Bins).
</PRE></BLOCKQUOTE>
<B>solve_bin/2</B> computes the sum of all components which is necessary
as a limit value for various domains, calls <B>bins/4</B> to
generate a list <B>Bins</B> with an increasing number of elements
and finally it labels all variables in the list:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
solve_bin(Demand, Bins) :-
    Demand = cont(G, P, S, W, C),
    Sum is G + P + S + W + C,
    bins(Demand, Sum, [Sum, Sum, Sum, Sum, Sum, Sum], Bins),
    label(Bins).
</PRE></BLOCKQUOTE>
The predicate to generate a list of bins with appropriate
constraints works as follows:
first it tries to match the amount of remaining components with zero
and the list with nil.
If this fails, a new bin represented by a list
<BLOCKQUOTE CLASS="quote">
<B>[<I>Colour</I>, <I>Glass</I>, <I>Plastic</I>, <I>Steel</I>, <I>Wood</I>, <I>Copper</I>]</B>
</BLOCKQUOTE>
is added to the bin list,
appropriate constraints are imposed on all the new bin's
variables,
its contents is subtracted from the remaining number of components,
and the predicate calls itself recursively:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
bins(cont(0, 0, 0, 0, 0), 0, _, []).
bins(cont(G0, P0, S0, W0, C0), Sum0, LastBin, [Bin|Bins]) :-
    Bin = [_Col, G, P, S, W, C],
    bin(Bin, Sum),
    G2 #= G0 - G,
    P2 #= P0 - P,
    S2 #= S0 - S,
    W2 #= W0 - W,
    C2 #= C0 - C,
    Sum2 #= Sum0 - Sum,
    ordering(Bin, LastBin),
    bins(cont(G2, P2, S2, W2, C2), Sum2, Bin, Bins).
</PRE></BLOCKQUOTE>
The <B>ordering/2</B> constraints are strictly necessary because
this problem has a huge number of symmetric solutions.<BR>
<BR>
The constraints imposed on a single bin correspond exactly to the
problem statement:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
bin([Col, G, P, S, W, C], Sum) :-
    Col :: [red, blue, green],
    [Capacity, G, P, S, W, C] :: 0..4,
    G + P + S + W + C #= Sum,
    Sum #&gt; 0,               % no empty bins
    Sum #&lt;= Capacity,
    capacity(Col, Capacity),
    contents(Col, G, P, S, W, C),
    requires(W, P),
    exclusive(G, C),
    exclusive(C, P),
    at_most(1, red, Col, W),
    at_most(2, green, Col, W).
</PRE></BLOCKQUOTE>
We will code all of the special constraints with the
maximum amount of propagation to show how this can be
achieved.
In most programs, however, it is not necessary to
propagate all values everywhere which simplifies the
code quite considerably.
Often it is also possible to use some of the built-in symbolic
constraints of ECL<SUP><I>i</I></SUP>PS<SUP><I>e</I></SUP>, e.g. <A HREF="../bips/lib/fd/element-3.html"><B>element/3</B></A><A NAME="@default157"></A> or <A HREF="../bips/lib/fd/atmost-3.html"><B>atmost/3</B></A><A NAME="@default158"></A>.<BR>
<BR>

<H4 CLASS="subsubsection">2.17.3.1&nbsp;&nbsp;Capacity Constraints</H4>
<B>capacity(Color, Capacity)</B> should instantiate the capacity
if the colour is known, and reduce the colour values
if the capacity is known to be greater than
some values.
If we use evaluation constraints, we can code the constraint directly,
using equivalences:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
capacity(Color, Capacity) :-
    Color #= blue #&lt;=&gt; Capacity #= 1,
    Color #= green #&lt;=&gt; Capacity #= 4,
    Color #= red #&lt;=&gt; Capacity #= 3.
</PRE></BLOCKQUOTE>
A more efficient code would take into account the ordering on the
capacities.
Concretely, if the capacity is greater than 1, the colour cannot
be blue and if it is greater than 3, it must be green:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
capacity(Color, Capacity) :-
    var(Color),
    !,
    dvar_domain(Capacity, DC),
    dom_range(DC, MinC, _),
    (MinC &gt; 1 -&gt;
        Color #\= blue,
        (MinC &gt; 3 -&gt;
            Color = green
        ;
            suspend(capacity(Color, Capacity), 3, (Color, Capacity)-&gt;inst)
        )
    ;
        suspend(capacity(Color, Capacity), 3, [Color-&gt;inst, Capacity-&gt;min])
    ).
capacity(blue, 1).
capacity(green, 4).
capacity(red, 3).
</PRE></BLOCKQUOTE>
Note that when suspended, the predicate waits for colour instantiation
or for minimum of the capacity to be updated (except that 3 is one less
than the maximum capacity and thus waiting for its instantiation
is equivalent).<BR>
<BR>

<H4 CLASS="subsubsection">2.17.3.2&nbsp;&nbsp;Containment Constraints</H4>
The containment constraints are stated as logical expressions
and this is also the easiest way to medel them.
The important point to remember is that a condition like
<I>red can contain glass, wood, copper</I>
actually means
<I>red cannot contain plastic or steel</I>
which can be written as
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
contents(Col, G, P, S, W, _) :-
    Col #= red #=&gt; P #= 0 #/\ S #= 0,
    Col #= blue #=&gt; P #= 0 #/\ W #= 0,
    Col #= green #=&gt; G #= 0 #/\ S #= 0.
</PRE></BLOCKQUOTE>
If we want to model the containment with low-level domain predicates,
it is easier to state them in the equivalent conjugate form:
<UL CLASS="itemize"><LI CLASS="li-itemize">
glass can be contained in red or blue
<LI CLASS="li-itemize">plastic can be contained in green
<LI CLASS="li-itemize">steel can be contained in blue
<LI CLASS="li-itemize">wood can be contained in red, green
<LI CLASS="li-itemize">copper can be contained in red, blue, green
</UL>
or in a further equivalent form that uses at most one bin colour:
<UL CLASS="itemize"><LI CLASS="li-itemize">
glass can not be contained in green
<LI CLASS="li-itemize">plastic can be contained in green
<LI CLASS="li-itemize">steel can be contained in blue
<LI CLASS="li-itemize">wood can not be contained in blue
<LI CLASS="li-itemize">copper can be contained in anything
</UL>
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
contents(Col, G, P, S, W, _) :-
    not_contained_in(Col, G, green),
    contained_in(Col, P, green),
    contained_in(Col, S, blue),
    not_contained_in(Col, W, blue).
</PRE></BLOCKQUOTE>
<B>contained_in(Color, Component, In)</B> states that
if Color is different from In, there can be no such component
in it, i.e. Component is zero:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
contained_in(Col, Comp, In) :-
    nonvar(Col),
    !,
    (Col \== In -&gt;
        Comp = 0
    ;
        true
    ).
contained_in(Col, Comp, In) :-
    dvar_domain(Comp, DM),
    dom_range(DM, MinD, _),
    (MinD &gt; 0 -&gt;
        Col = In
    ;
        suspend(contained_in(Col, Comp, In), 2, [Comp-&gt;min, Col-&gt;inst])
    ).
</PRE></BLOCKQUOTE>
<B>not_contained_in(Color, Component, In)</B> states that if the bin is of the given
colour, the component cannot be contained in it:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
not_contained_in(Col, Comp, In) :-
    nonvar(Col),
    !,
    (Col == In -&gt;
        Comp = 0
    ;
        true
    ).
not_contained_in(Col, Comp, In) :-
    dvar_domain(Comp, DM),
    dom_range(DM, MinD, _),
    (MinD &gt; 0 -&gt;
        Col #\= In
    ;
        suspend(not_contained_in(Col, Comp, In), 2, [Comp-&gt;min, Col-&gt;any])
    ).
</PRE></BLOCKQUOTE>
As you can see again, modeling with the low-level domain predicates
might give a faster and more precise programs,
but it is much more difficult than using constraint
expressions and evaluation constraints.
A good approach is thus to start with constraint expressions
and only if they are not efficient enough, to (stepwise) recode
some or all constraints with the low-level predicates.<BR>
<BR>

<H4 CLASS="subsubsection">2.17.3.3&nbsp;&nbsp;Requirement Constraints</H4>
The constraint `A requires B' is written as
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
requires(A, B) :-
    A #&gt; 0 #=&gt; B #&gt; 0.
</PRE></BLOCKQUOTE>
With low-level predicates,
the constraint `A requires B' is woken as soon as some
A is present or B is known:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
requires(A, B) :-
    nonvar(B),
    !,
    ( B = 0 -&gt;
        A = 0
    ;
        true
    ).
requires(A, B) :-
    dvar_domain(A, DA),
    dom_range(DA, MinA, _),
    ( MinA &gt; 0 -&gt;
        B #&gt; 0
    ;
        suspend(requires(A, B), 2, [A-&gt;min, B-&gt;inst])
    ).
</PRE></BLOCKQUOTE>

<H4 CLASS="subsubsection">2.17.3.4&nbsp;&nbsp;Exclusive Constraints</H4>
The exclusive constraint can be written as
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
exclusive(A, B) :-
    A #&gt; 0 #=&gt; B #= 0,
    B #&gt; 0 #=&gt; A #= 0.
</PRE></BLOCKQUOTE>
however a simple form with one disjunction is enough:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
exclusive(A, B) :-
    A #= 0 #\/ B #= 0.
</PRE></BLOCKQUOTE>
With low-level domain predicates,
the exclusive constraint defines a suspension which is woken
as soon as one of the two components is present:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
exclusive(A, B) :-
    dvar_domain(A, DA),
    dom_range(DA, MinA, MaxA),
    ( MinA &gt; 0 -&gt;
        B = 0
    ; MaxA = 0 -&gt;
        % A == 0
        true
    ;
        dvar_domain(B, DB),
        dom_range(DB, MinB, MaxB),
        ( MinB &gt; 0 -&gt;
            A = 0
        ; MaxB = 0 -&gt;
            % B == 0
            true
        ;
            suspend(exclusive(A, B), 3, (A,B)-&gt;min)
        )
    ).
</PRE></BLOCKQUOTE>

<H4 CLASS="subsubsection">2.17.3.5&nbsp;&nbsp;Atmost Constraints</H4>
<B>at_most(N, In, Colour, Components)</B> states that if Colour
is equal to In, then there can be at most N Components
and vice versa, if there are more than N Components, the colour
cannot be In.
With constraint expressions, this can be simply coded as
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
at_most(N, In, Col, Comp) :-
    Col #= In #=&gt; Comp #&lt;= N.
</PRE></BLOCKQUOTE>
A low-level solution looks as follows:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
at_most(N, In, Col, Comp) :-
    nonvar(Col),
    !,
    (In = Col -&gt;
        Comp #&lt;= N
    ;
        true
    ).
at_most(N, In, Col, Comp) :-
    dvar_domain(Comp, DM),
    dom_range(DM, MinM, _),
    (MinM &gt; N -&gt;
        Col #\= In
    ;
        suspend(at_most(N, In, Col, Comp), 2, [In-&gt;inst, Comp-&gt;min])
    ).
</PRE></BLOCKQUOTE>

<H4 CLASS="subsubsection">2.17.3.6&nbsp;&nbsp;Ordering Constraints</H4>
To filter out symmetric solutions we can e.g. impose a lexicographic
ordering on the bins in the list, i.e. the second bin must be
lexicographically greater or equal than the first one etc.
As long as the corresponding most significant
variables in two consecutive bins
are not instantiated, we cannot constrain the following ones
and thus we suspend the ordering on the <B>inst</B> lists:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
ordering([], []).
ordering([Val1|Bin1], [Val2|Bin2]) :-
    Val1 #&lt;= Val2,
    (integer(Val1) -&gt;
        (integer(Val2) -&gt;
            (Val1 = Val2 -&gt;
                ordering(Bin1, Bin2)
            ;
                true
            )
        ;
            suspend(ordering([Val1|Bin1], [Val2|Bin2]), 2, Val2-&gt;inst)
        )
    ;
        suspend(ordering([Val1|Bin1], [Val2|Bin2]), 2, Val1-&gt;inst)
    ).
</PRE></BLOCKQUOTE>
There is a problem with the representation of the colour:
If the colour is represented by an atom, we cannot apply
the <B>#</B><CODE><B>&lt;=</B></CODE><B>/2</B> predicate on it.
To keep the ordering predicate simple and still have a symbolic
representation of the colour in the program, we can define
input macros that transform the colour atoms into integers:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
:- define_macro(no_macro_expansion(blue)/0, tr_col/2, []).
:- define_macro(no_macro_expansion(green)/0, tr_col/2, []).
:- define_macro(no_macro_expansion(red)/0, tr_col/2, []).

tr_col(no_macro_expansion(red), 1).
tr_col(no_macro_expansion(green), 2).
tr_col(no_macro_expansion(blue), 3).
</PRE></BLOCKQUOTE>

<H4 CLASS="subsubsection">2.17.3.7&nbsp;&nbsp;Labeling</H4>
A straightforward labeling would be to flatten the list with
the bins and use e.g. <A HREF="../bips/lib/fd/deleteff-3.html"><B>deleteff/3</B></A><A NAME="@default159"></A> to label a variable out of it.
However, for this example not all variables have the same
importance &mdash; the colour variables propagate much more data
when instantiated.
Therefore, we first filter out the colours and label
them before all the component variables:
<BLOCKQUOTE CLASS="quote">
<PRE CLASS="verbatim">
label(Bins) :-
    colours(Bins, Colors, Things),
    flatten(Things, List),
    labeleff(Colors),
    labeleff(List).

colours([], [], []).
colours([[Col|Rest]|Bins], [Col|Cols], [Rest|Things]) :-
    colours(Bins, Cols, Things).

labeleff([]).
labeleff(L) :-
    deleteff(V, L, Rest),
    indomain(V),
    labeleff(Rest).
</PRE></BLOCKQUOTE>
Note also that we need a special version of <B>flatten/3</B>
that works with nonground lists.<BR>
<BR>
<A NAME="toc18"></A>
<H2 CLASS="section"><A NAME="htoc28">2.18</A>&nbsp;&nbsp;Current Known Restrictions and Bugs</H2>
<OL CLASS="enumerate" type=1><LI CLASS="li-enumerate">The default domain for integer finite domain variables
is -10000000..10000000.
Larger domains must be stated explicitly using the ::/2 predicate,
however neither bound can be outside the standard integer
range for the machine (usually 32 bits).<BR>
<BR>
<LI CLASS="li-enumerate">Linear integer terms are processed using machine integers
and thus if the maximum or minimum value of a linear term
overflows this range (usually 32 bits), incorrect results
are reported.
This may occur if large coefficients are used, if domains are
too large or a combination of the two.</OL>
<A NAME="@default160"></A>

<HR>
<A HREF="obsman001.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Up"></A>
<A HREF="obsman003.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
